package meter

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

// DBType represents the database type for electrical write operations
// DBType 表示电表写入操作的数据库类型
type DBType int

// DBType constants for electrical write operations
// 电表写入操作的数据库类型常量
const (
	DBTypeRatePrice DBType = 12 // 设置费率电价
	DBTypeStepPrice DBType = 13 // 设置阶梯电价
	// DBTypeVoltageTransformer DBType = 23  // 设置电压互感器变比
	DBTypeLoadLimitPower DBType = 122 // 负荷限制功率
	// DBTypeTimezone           DBType = 126 // 设置时区
	// DBTypeDayTimeTable1      DBType = 129 // 设置日时段表1
	// DBTypeDayTimeTable2      DBType = 130 // 设置日时段表2
	// DBTypeDayTimeTable3      DBType = 185 // 设置日时段表3（部份表支持）
	// DBTypeDayTimeTable4      DBType = 186 // 设置日时段表4（部份表支持）
)

// String returns the string representation of DBType
// String 返回DBType的字符串表示
func (d DBType) String() string {
	switch d {
	case DBTypeRatePrice:
		return "设置费率电价"
	case DBTypeStepPrice:
		return "设置阶梯电价"
	case DBTypeLoadLimitPower:
		return "负荷限制功率"
	default:
		return fmt.Sprintf("未知类型(%d)", int(d))
	}
}

type EleWriteParams interface {
	Type() DBType
	Validate() error
}

type RateEleTariffRequest struct {
	P1 int `json:"p1"`
	P2 int `json:"p2"`
	P3 int `json:"p3"`
	P4 int `json:"p4"`
}

func (r *RateEleTariffRequest) Type() DBType {
	return DBTypeRatePrice
}

func (r *RateEleTariffRequest) Validate() error {
	if r.P1 <= 0 {
		return fmt.Errorf("p1 (尖电价) must be greater than 0, got %d", r.P1)
	}
	if r.P2 <= 0 {
		return fmt.Errorf("p2 (峰电价) must be greater than 0, got %d", r.P2)
	}
	if r.P3 <= 0 {
		return fmt.Errorf("p3 (平电价) must be greater than 0, got %d", r.P3)
	}
	if r.P4 <= 0 {
		return fmt.Errorf("p4 (谷电价) must be greater than 0, got %d", r.P4)
	}
	return nil
}

type LoadLimitPowerRequest struct {
	P1 float64 `json:"p1"`
}

func (r *LoadLimitPowerRequest) Type() DBType {
	return DBTypeLoadLimitPower
}

func (r *LoadLimitPowerRequest) Validate() error {
	if r.P1 < 0 {
		return fmt.Errorf("p1 (负荷限制功率) must be greater than or equal to 0, got %.4f", r.P1)
	}
	// 负荷限制功率范围：0-99.9999kW
	if r.P1 > 99.9999 {
		return fmt.Errorf("p1 (负荷限制功率) must not exceed 99.9999kW, got %.4f", r.P1)
	}
	return nil
}

// EleWriteRequest represents the request parameters for electrical write API
type EleWriteRequest struct {
	Address string `json:"address" v:"required"` // 设备列表的address
	CID     string `json:"cid" v:"required"`     // 设备列表的cid
	DBType  DBType `json:"dbType"`               // 类型
	Params  g.Map  `json:"params"`               // 类型对应的参数
}

// EleWriteResponse represents the complete response from electrical write API
type EleWriteResponse struct {
	Code    int    `json:"code"`    // 响应状态码
	Message string `json:"message"` // 响应消息
}

// StatisticEleRequest, MeterStatistic, StatisticEleData, and StatisticEleResponse are now defined in models_ele_statistic.go

// StatisticEleRequest validation methods are now defined in models_ele_statistic.go

// Validate validates the EleWriteRequest parameters using GoFrame validation
func (r *EleWriteRequest) Validate() error {
	// Validate the struct fields using GoFrame
	if err := g.Validator().Data(r).Run(context.Background()); err != nil {
		return err
	}

	// Check if Params is not nil
	if r.Params == nil {
		return fmt.Errorf("params cannot be nil")
	}

	// Validate parameters based on DBType
	switch r.DBType {
	case DBTypeRatePrice:
		// Validate rate electricity tariff parameters
		p1, ok := r.Params["p1"]
		if !ok {
			return fmt.Errorf("p1 (尖电价) is required")
		}
		p1Value := gconv.Int(p1)
		if p1Value <= 0 {
			return fmt.Errorf("p1 (尖电价) must be greater than 0, got %d", p1Value)
		}

		p2, ok := r.Params["p2"]
		if !ok {
			return fmt.Errorf("p2 (峰电价) is required")
		}
		p2Value := gconv.Int(p2)
		if p2Value <= 0 {
			return fmt.Errorf("p2 (峰电价) must be greater than 0, got %d", p2Value)
		}

		p3, ok := r.Params["p3"]
		if !ok {
			return fmt.Errorf("p3 (平电价) is required")
		}
		p3Value := gconv.Int(p3)
		if p3Value <= 0 {
			return fmt.Errorf("p3 (平电价) must be greater than 0, got %d", p3Value)
		}

		p4, ok := r.Params["p4"]
		if !ok {
			return fmt.Errorf("p4 (谷电价) is required")
		}
		p4Value := gconv.Int(p4)
		if p4Value <= 0 {
			return fmt.Errorf("p4 (谷电价) must be greater than 0, got %d", p4Value)
		}

	case DBTypeLoadLimitPower:
		// Validate load limit power parameters
		p1, ok := r.Params["p1"]
		if !ok {
			return fmt.Errorf("p1 (负荷限制功率) is required")
		}
		p1Value := gconv.Float64(p1)
		if p1Value < 0 {
			return fmt.Errorf("p1 (负荷限制功率) must be greater than or equal to 0, got %.4f", p1Value)
		}
		// 负荷限制功率范围：0-99.9999kW
		if p1Value > 99.9999 {
			return fmt.Errorf("p1 (负荷限制功率) must not exceed 99.9999kW, got %.4f", p1Value)
		}
	}

	return nil
}
